#include <int.h>
#include <printk.h>
#include <pm.h>
#include <types.h>
#include <interrupt.h>

extern uint8_t idtCount;

/*   硬件中断处理函数   */
extern void  hwint_00(void);
extern void  hwint_01(void);
extern void  hwint_02(void);
extern void  hwint_03(void);
extern void  hwint_04(void);
extern void  hwint_05(void);
extern void  hwint_06(void);
extern void  hwint_07(void);
extern void  hwint_08(void);
extern void  hwint_09(void);
extern void  hwint_10(void);
extern void  hwint_11(void);
extern void  hwint_12(void);
extern void  hwint_13(void);
extern void  hwint_14(void);
extern void  hwint_15(void);
/*   汇编的异常处理函数   */
extern void Handle_Trap_DE0(void);     //;
extern void Handle_Trap_DB(void);      //  1: Debug */
extern void Handle_Trap_NMI(void);     //  2: Non-maskable Interrupt */
extern void Handle_Trap_BP(void);      //  3: Breakpoint */
extern void Handle_Trap_OF(void);      //  4: Overflow */
extern void Handle_Trap_BR(void);      //  5: Bound Range Exceeded */
extern void Handle_Trap_UD(void);      //  6: Invalid Opcode */
extern void Handle_Trap_NM(void);      //  7: Device Not Available */
extern void Handle_Trap_DF(void);      //  8: Double Fault */
extern void Handle_Trap_OLD_MF(void);  //  9: Coprocessor Segment Overrun */
extern void Handle_Trap_TS(void);      // 10: Invalid TSS */
extern void Handle_Trap_NP(void);      // 11: Segment Not Present */
extern void Handle_Trap_SS(void);      // 12: Stack Segment Fault */
extern void Handle_Trap_GP(void);      // 13: General Protection Fault */
extern void Handle_Trap_PF(void);      // 14: Page Fault */
extern void Handle_Trap_SPURIOUS(void);//15: Spurious Interrupt */
extern void Handle_Trap_MF(void);      // 16: x87 Floating-Point Exception */
extern void Handle_Trap_AC(void);      // 17: Alignment Check */
extern void Handle_Trap_MC(void);      // 18: Machine Check */
extern void Handle_Trap_XF(void);      // 19: SIMD Floating-Point Exception */
extern void Handle_Trap_IRET(void);    // 32: IRET Exception */


/*   异常提示信息   */
static char *excepMsg[] = {
    "Division By Zero",
    "Debug",
    "Non Maskable Interrupt",
    "Breakpoint",
    "Into Detected Overflow",
    "Out of Bounds",
    "Invalid Opcode",
    "No Coprocessor",

    "Double Fault",
    "Coprocessor Segment Overrun",
    "Bad TSS",
    "Segment Not Present",
    "Stack Fault",
    "General Protection Fault",
    "Page Fault",
    "Unknown Interrupt",

    "Coprocessor Fault",
    "Alignment Check",
    "Machine Check",

    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",

    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved"
};


struct idt_content irqTable[] = {

    /*   异常中断   */
    { X86_TRAP_DE, Handle_Trap_DE0},
    { X86_TRAP_DB, Handle_Trap_DB},
    { X86_TRAP_NMI, Handle_Trap_NMI},
    { X86_TRAP_BP, Handle_Trap_BP},
    { X86_TRAP_OF, Handle_Trap_OF},
    { X86_TRAP_BR, Handle_Trap_BR},
    { X86_TRAP_UD, Handle_Trap_UD},
    { X86_TRAP_NM, Handle_Trap_NM},
    { X86_TRAP_DF, Handle_Trap_DF},
    { X86_TRAP_OLD_MF, Handle_Trap_OLD_MF},
    { X86_TRAP_TS, Handle_Trap_TS},
    { X86_TRAP_NP, Handle_Trap_NP},
    { X86_TRAP_SS, Handle_Trap_SS},
    { X86_TRAP_GP, Handle_Trap_GP},
    { X86_TRAP_PF, Handle_Trap_PF},
    { X86_TRAP_SPURIOUS, Handle_Trap_SPURIOUS},
    { X86_TRAP_MF, Handle_Trap_MF},
    { X86_TRAP_AC, Handle_Trap_AC},
    { X86_TRAP_MC, Handle_Trap_MC},
    { X86_TRAP_XF, Handle_Trap_XF},
    { X86_TRAP_IRET, Handle_Trap_IRET},

    /*    硬件中断  */
    { CLOCK_IRQ + HW_IRQ_BASE, hwint_00},            //时钟中断
    { KEYBOARD_IRQ + HW_IRQ_BASE, hwint_01},
    { CASCADE_IRQ + HW_IRQ_BASE, hwint_02},
    { ETHER_IRQ + HW_IRQ_BASE, hwint_03},
    { SECONDARY_IRQ + HW_IRQ_BASE, hwint_04},
    { RS232_IRQ + HW_IRQ_BASE, hwint_05},
    { XT_WINI_IRQ + HW_IRQ_BASE, hwint_06},
    { FLOPY_IRQ + HW_IRQ_BASE, hwint_07},
    { PRINTER_IRQ + HW_IRQ_BASE, hwint_08},
    { REAL_CLOCK_IRQ + HW_IRQ_BASE, hwint_09},
    { DRECT_IRQ2_IRQ + HW_IRQ_BASE, hwint_10},
    { RESERVED_10_IRQ + HW_IRQ_BASE, hwint_11},
    { RESERVED_11_IRQ + HW_IRQ_BASE, hwint_12},
    { MOUSE_IRQ + HW_IRQ_BASE, hwint_13},
    { FPU_IRQ + HW_IRQ_BASE, hwint_14},
    { AT_WINI_IRQ + HW_IRQ_BASE, hwint_15},
    //{ RESERVED_15_IRQ + HW_IRQ_BASE, hwint_16},
    { NR_IRQS, NULL},
};


void idt_table_init(void)
{
    struct idt_content *piDesc = irqTable;
    while(piDesc->index != NR_IRQS){
        idt_install(piDesc->index, (uint32_t)piDesc->handler, seg_to_sel(SEG_CODE_SYS), DA_386IGATE);
        piDesc++;
    }
    idtCount = AT_WINI_IRQ + HW_IRQ_BASE;
}


void ExceptionHandler(uint8_t index, uint32_t retNum)
{
    printk("========================  EXCEPTION :%d  ========================\n",excepMsg[index]);
    printk("Exception num:%d\nReturn Code: %d\nException Message: %s\n",index, retNum,excepMsg[index]);
}